package com.cloudkinto.service.order.impl;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import javax.net.ssl.*;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.util.*;
import java.util.concurrent.TimeUnit;

public class RakutenUtil {
    public static String raAPidoGet(String serviceUrl, String secret, String license, Map parametersMap) throws Exception {
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("Authorization", getBase64ESA(secret,license));
        headerMap.put("content-type", "application/xml; charset=utf-8");
        if (parametersMap.size() > 0)
            serviceUrl = serviceUrl + "?" + sortParams(parametersMap);
        InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 1081);
        Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); // http 代理
        OkHttpClient.Builder builder = getUnsafeOkHttpClient().newBuilder();
        builder.connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .proxy(proxy)
                .retryOnConnectionFailure(false);
        Request.Builder requestBuilder = createSPHeader(headerMap);
        Request request = requestBuilder.url(serviceUrl).get().build();
        Response response = null;
        String body = "";
        response = builder.build().newCall(request).execute();
        body = response.body().string();
//        System.out.println(body);
        return body;
    }

    public static String getBase64ESA(String secret,String license){
        byte[] pass = (secret.trim() + ":" + license.trim()).getBytes(StandardCharsets.UTF_8);
        return "ESA " + Base64.getEncoder().encodeToString(pass);
    }


    /**
     * 构建header参数
     *
     * @param headerMap
     * @return
     */
    public static Request.Builder createSPHeader(Map<String, String> headerMap) {
        Request.Builder requestBuilder = new Request.Builder();
        Iterator<Map.Entry<String, String>> pairs =
                headerMap.entrySet().iterator();
        while (pairs.hasNext()) {
            Map.Entry<String, String> data = pairs.next();
            requestBuilder.addHeader(data.getKey(), data.getValue());
        }
        return requestBuilder;
    }


    /**
     * 1.1 对传递参数转换(Body)
     *
     * @param parameters
     * @return
     */
    public static String sortParams(Map<String, Object> parameters) {
        StringBuilder data = new StringBuilder();
        if (parameters == null) return "";
        Map<String, Object> sorted = new TreeMap<String, Object>();
        sorted.putAll(parameters);
        Iterator<Map.Entry<String, Object>> pairs =
                sorted.entrySet().iterator();
        while (pairs.hasNext()) {
            Map.Entry<String, Object> pair = pairs.next();
            if (pair.getValue() != null) {
                data.append(URLEncoder.encode(pair.getKey()) + "=" + URLEncoder.encode(pair.getValue().toString()));
            } else {
                data.append(URLEncoder.encode(pair.getKey()) + "=");
            }
            if (pairs.hasNext()) {
                data.append("&");
            }
        }
//        System.out.println("参数转换(Body)\n" + data.toString());
        return data.toString();
    }



    public static OkHttpClient getUnsafeOkHttpClient() {
        try {
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory,getX509TrustManager());

            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            return builder.build();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static X509TrustManager getX509TrustManager() {
        X509TrustManager trustManager = null;
        try {
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore) null);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
                throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
            }
            trustManager = (X509TrustManager) trustManagers[0];
        } catch (Exception e) {
            e.printStackTrace();
        }

        return trustManager;
    }
}
